package com.dayuanit.pay.bank.handler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dayuanit.pay.bank.domain.SinaPayQuery;
import com.dayuanit.pay.bank.domain.SinaPayRequest;
import com.dayuanit.pay.bank.domain.SinaPayResponse;
import com.dayuanit.pay.domain.PayOrder;
import com.dayuanit.pay.exception.MallBusException;
import com.dayuanit.pay.util.DateUtil;
import com.dayuanit.pay.util.DyCodecUtil;

/**
 * 新浪支付处理类
 * @author Administrator
 *
 */
@Component("sinaPayHandler")
public class SinaPayHandler extends PayBaseHandler {
	
	@Value("#{configProperties['sinapay_order_pay_gateway_product']}")
	private String productOrderPayUrl;
	
	@Value("#{configProperties['sinapay_order_pay_gateway_test']}")
	private String testOrderPayUrl = "xxxxx";
	
	
	@Value("#{configProperties['sinapay_order_query_gateway_test']}")
	private String testOrderQueryPayUrl = "xxxxx";
	
	@Value("#{configProperties['sinapay_order_query_gateway_product']}")
	private String productOrderQueryPayUrl = "xxxxx";
	
	@Value("#{configProperties['sinapay_bgurl_product']}")
	private String productBgUrl = "xxxx";
	
	@Value("#{configProperties['sinapay_bgurl_test']}")
	private String testBgUrl = "xxxx";
	
	@Value("#{configProperties['sinapay_merchant_acct_id']}")
	private String merchantAcctId = "";
	
	@Value("#{configProperties['sinapay_pid']}")
	private String pid = "";
	
	@Value("#{configProperties['sinapay_sign_type']}")
	private String signType = "";
	
	@Value("#{configProperties['sinapay_md5_key']}")
	private String key = "xxx";
	
	@Value("#{configProperties['sinapay_des_key']}")
	private String desKey = "xxx";
	
	@Value("#{configProperties['sinapay_pay_environment']}")
	private boolean payEnvironment;
	
	private static final String PAY_SUCCESS_FLAG = "10";

	@Override
	protected String getOrderPayUrl() {
		return payEnvironment ? productOrderPayUrl : testOrderPayUrl;
	}
	
	private String getBgUrl() {
		return payEnvironment ? productBgUrl : testBgUrl;
	}

	@Override
	protected Map<String, Object> getOrderPayParam(PayOrder payOrder) {
		
		SinaPayRequest sr = SinaPayRequest.instance()
				.setBgUrl(getBgUrl())
				.setMerchantAcctId(merchantAcctId)
				.setOrderAmount(payOrder.getAmount())
				.setOrderId(String.valueOf(payOrder.getId()))
				.setOrderTime(DateUtil.dateToString(payOrder.getModifyTime(), DateUtil.PATTERN_YYYYMMDDHHMMSS))
				.setPid(pid)
				.setSignType(signType);
		
		String origin = sr.createSignOrigin(key);
		String signMsg = MD5(origin);
		sr.setSignMsg(signMsg);
		
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("inputCharset", sr.getInputCharset());
		param.put("bgUrl", sr.getBgUrl());
		param.put("version", sr.getVersion());
		param.put("language", sr.getLanguage());
		param.put("signType", sr.getSignType());
		param.put("merchantAcctId", sr.getMerchantAcctId());
		param.put("orderId", sr.getOrderId());
		param.put("orderAmount", sr.getOrderAmount());
		param.put("orderTime", sr.getOrderTime());
		param.put("payType", SinaPayRequest.getPayType());
		param.put("pid", sr.getPid());
		param.put("signMsg", sr.getSignMsg());
		
		return param;
	}
	
	private String MD5(String msg) {
		return DigestUtils.md5Hex(msg);
	}
	
	private String DES(String msg) {
		return DyCodecUtil.encodeMsg(msg.getBytes(), desKey.getBytes());
	}
	
	public boolean checkNotifySigin(String sign, SinaPayResponse sr) {
		return MD5(sr.createOrigin(key)).equals(sign);
	}
	
	
	@Override
	public boolean orderSearch(PayOrder payOrder) throws Exception {
		
		log.info("查询订单{}", payOrder.getId());
		SinaPayQuery query = SinaPayQuery.instance().setDealId("")
								.setMerchantId(merchantAcctId)
								.setOrderId(String.valueOf(payOrder.getId()))
								.setSignType(signType);
		
		String origin = query.createSignOrigin();
		String signMsg = MD5(origin + key);
		
		query.setSignMsg(signMsg);
		
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(getOrderQueryPayUrl());
		
		List <NameValuePair> nvps = new ArrayList <NameValuePair>();
		nvps.add(new BasicNameValuePair("inputCharset", query.getInputCharset()));
		nvps.add(new BasicNameValuePair("version", query.getVersion()));
		nvps.add(new BasicNameValuePair("merchantId", query.getMerchantId()));
		nvps.add(new BasicNameValuePair("orderId", query.getOrderId()));
		nvps.add(new BasicNameValuePair("dealId", query.getDealId()));
		nvps.add(new BasicNameValuePair("signType", query.getSignType()));
		nvps.add(new BasicNameValuePair("signMsg", query.getSignMsg()));
		
		httpPost.setEntity(new UrlEncodedFormEntity(nvps));
		CloseableHttpResponse response = httpclient.execute(httpPost);
	    HttpEntity entity = (HttpEntity)response.getEntity();
	    
	    String msg = EntityUtils.toString(entity);
		log.info("支付系统查询新浪网管返回的数据:{}", msg);
		
		JSONObject jo = JSON.parseObject(msg);
		boolean success = jo.getBoolean("success");
		if (!success) {
			throw new MallBusException("查询订单失败");
		}
		
		if (StringUtils.isBlank(jo.getString("data"))) {
			throw new MallBusException("查询返回数据不正确");
		}
		
		log.info("==========" + jo.getString("data"));
		SinaPayResponse sinpay = JSON.parseObject(jo.getString("data"), SinaPayResponse.class);
		
		
		String payResult = sinpay.getPayResult();
		
		return PAY_SUCCESS_FLAG.equals(payResult);
	}

	@Override
	protected String getOrderQueryPayUrl() {
		return payEnvironment ? productOrderQueryPayUrl : testOrderQueryPayUrl;
	}
	

}
